/*******************************************************************************
 * eWisdom : a Distributed File Sharing Room on top of a p2p Overlay Network
 * Copyright (C) 2009-2010 Jesus Mari Aguirre
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 ******************************************************************************/

package org.jma.app.ewisdom.services;

import easypastry.dht.DHTHandler;
import easypastry.dht.DHTException;
import easypastry.core.PastryKernel;
import easypastry.util.Utilities;

import org.jma.app.ewisdom.entities.Group;
import org.jma.app.ewisdom.entities.GroupVector;
import org.jma.app.ewisdom.entities.User;
import org.jma.app.ewisdom.entities.UserVector;
import org.jma.app.ewisdom.exceptions.GroupException;
import org.jma.app.ewisdom.exceptions.UserException;
import org.jma.lib.soap.SOAPProxy;
import org.jma.lib.soap.sessions.SOAPSession;


import java.util.HashMap;
import java.util.Vector;

/**
 * SrvGroupManager class allows the management of Groups. It publishes
 * methods as services described below.<br>
 * @author Jesus Mari, jesmari@ono.com
 * @version 1.0
 * @since 1.0
 */
public class SrvGroupManager {

	/**
	 * Checks if a user is a wheel group member
	 * @param currentUser
	 * @return true or false
	 * @throws GroupException
	 */
	private boolean checkGroup(String currentUser) throws  GroupException{
		//if (currentUser.equals(userName)) return false;		
		HashMap soapParams=new HashMap();
		soapParams.put("groupName", "wheel");
		Group g=this.getGroup(soapParams);
		Vector u=g.getUsers();
		if (u.contains(currentUser)) return false;
		return true;
	}

	/**
	 * gets a group
	 * @param soapParams <code>groupName</code> the group name.
	 * @return a Group
	 * @throws GroupException
	 */
	public Group getGroup (HashMap soapParams) throws GroupException {

		String gn=(String)soapParams.get("groupName");
		String currentUser = ((SOAPSession)soapParams.get(SOAPProxy.SOAPSession)).getUserName();
		if (checkGroup(currentUser)) throw new GroupException("Insufficient privileges");

		Group group;
		try {
			DHTHandler dhtGroup = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.groups"));

			group = (Group) dhtGroup.get(gn);
		} catch (DHTException e) {
			throw new GroupException(e.getMessage());
		}

		return group;

	}

	/**
	 * adds a group
	 * @param soapParams <code>groupName</code> the group name, <code>description</code> a description.
	 * @return a new Group
	 * @throws GroupException
	 */
	public Group addGroup (HashMap soapParams) throws GroupException {
		SOAPSession session=((SOAPSession)soapParams.get(SOAPProxy.SOAPSession));
		if (session!=null){
			String currentUser = session.getUserName();
			if (checkGroup(currentUser)) throw new GroupException("Insufficient privileges");

		}
		
		try {
			DHTHandler dhtGroup = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.groups"));

			Group gr= new Group();
			gr.setGroupName((String)soapParams.get("groupName"));
			gr.setDescription((String)soapParams.get("description"));
			dhtGroup.put(gr.getGroupName(),gr);
			addGroupToCollection(gr);
			return gr;
		} catch (DHTException e) {
			throw new GroupException(e.getMessage());
		}
	}

	/**
	 * joins a User to a group
	 * @param soapParams <code>groupName</code> the group name, <code>userName</code> a user name.
	 * @return a Group
	 * @throws GroupException
	 */
	public Group joinUserToGroup (HashMap soapParams) throws GroupException {
		SOAPSession session = (SOAPSession)soapParams.get(SOAPProxy.SOAPSession);
		if (session!=null){
			String currentUser = session.getUserName();
			if (checkGroup(currentUser)) throw new GroupException("Insufficient privileges");
		}
		try {
			DHTHandler dhtGroup = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.groups"));

			SrvUserManager sum = new SrvUserManager();
			Group gr= this.getGroup(soapParams);
			User u = sum.joinUserToGroup(soapParams);
			gr.addUser(u.getUserName());
			dhtGroup.put(gr.getGroupName(),gr);
			removeGroupFromCollection(gr);
			addGroupToCollection(gr);
			return gr;
		} catch (DHTException e) {
			throw new GroupException(e.getMessage());
		} catch (UserException e) {
			// TODO Auto-generated catch block
			throw new GroupException(e.getMessage());
		}
	}
	
	/**
	 * adds a Group to the all groups collection
	 * @param gr a Group
	 * @throws GroupException
	 */
	private void addGroupToCollection  (Group gr) throws GroupException {

		try {
			DHTHandler dhtGroup = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.groups"));

			GroupVector set = (GroupVector) dhtGroup.get("groups.Vector");
		
			if (set == null) {
				set = new GroupVector();
			}
			set.add(gr.clone());
			dhtGroup.put("groups.Vector", set);
		} catch (DHTException e) {
			throw new GroupException(e.getMessage());
		}
	}
	/**
	 * deletes a Group from the all groups collection
	 * @param gr a Group
	 * @throws GroupException
	 */
	private void removeGroupFromCollection  (Group gr) throws GroupException {

		try {
			DHTHandler dhtGroup = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.groups"));

			GroupVector set = (GroupVector) dhtGroup.get("groups.Vector");
			if (set == null) {
				set = new GroupVector();
			}
			set.remove(gr);
			dhtGroup.put("groups.Vector", set);
		} catch (DHTException e) {
			throw new GroupException(e.getMessage());
		}
	}    

	/**
	 * Return a GroupVector that contains all the groups.
	 * @param soapParams no parameters defined.
	 * @return
	 * @throws GroupException
	 */
	public GroupVector getGroups (HashMap soapParams) throws GroupException{
		String currentUser = ((SOAPSession)soapParams.get(SOAPProxy.SOAPSession)).getUserName();
		if (checkGroup(currentUser)) throw new GroupException("Insufficient privileges");

		try {
			DHTHandler dhtGroup = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.groups"));

			GroupVector set = (GroupVector) dhtGroup.get("groups.Vector");
			return set;
		} catch (DHTException e) {
			throw new GroupException(e.getMessage());
		}
	}

	/**
	 * removes a Group
	 * @param soapParams <code>groupName</code> the group name.
	 * @return a removed Group
	 * @throws GroupException
	 */
	public Group removeGroup(HashMap soapParams) throws GroupException{
		String currentUser = ((SOAPSession)soapParams.get(SOAPProxy.SOAPSession)).getUserName();
		if (checkGroup(currentUser)) throw new GroupException("Insufficient privileges");

		String groupName=(String)soapParams.get("groupName");   	  
		Group group;
		try {
			DHTHandler dhtGroup = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.groups"));

			group = (Group) dhtGroup.get(groupName);
			dhtGroup.remove(groupName);
			removeGroupFromCollection(group);
		} catch (DHTException e) {
			throw new GroupException(e.getMessage());
		}      

		return group;

	}
}
